home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / AOCE / Development Tools / Sample Code / Interprogram Messaging Manager / IPM MessageBoard / MyIPM.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-23  |  18.6 KB  |  800 lines  |  [TEXT/MPS ]

  1. /*-------------------------------------------------------------------------------------
  2.  *
  3.  * IPM MessageBoard AOCE Sample
  4.  *
  5.  * ©1992-1993 Apple Computer
  6.  *
  7.  -------------------------------------------------------------------------------------*/
  8. /*
  9.  * commands.c -- called in response to menu commands or appleevents
  10.  *
  11.  * change history:
  12.  *
  13.  * SJF        2/12/93        1.0b1        udpate to AOCE beta seed
  14.  * SJF        11/6/91        1.0d1        initial coding
  15.  *
  16.  */
  17.  
  18. #ifndef __TOOLUTILS__
  19. #include <ToolUtils.h>
  20. #endif
  21.  
  22. #ifndef __RESOURCES__
  23. #include <Resources.h>
  24. #endif
  25.  
  26. #include <string.h>
  27.  
  28. #ifdef THINK_C                /* MPW includes            */
  29. #include <pascal.h>
  30. #endif
  31.  
  32. #ifndef    __OCE__
  33. #include <OCE.h>
  34. #endif
  35.  
  36. #ifndef __OCEMESSAGING__
  37. #include <OCEMessaging.h>
  38. #endif
  39.  
  40. #ifndef __OCEERRORS__
  41. #include <OCEErrors.h>
  42. #endif
  43.  
  44. #ifndef __OCESTANDARDMAIL__
  45. #include <OCEStandardMail.h>
  46. #endif
  47.  
  48. #ifndef __OCESTANDARDDIRECTORY__
  49. #include <OCEStandardDirectory.h>
  50. #endif
  51.  
  52. #ifndef __OCETEMPLATES__
  53. #include <OCETemplates.h>
  54. #endif
  55.  
  56. #ifdef applec
  57. #include <strings.h>    // for c2pstr
  58. #endif
  59.  
  60. #include "const.h"
  61. #include "globals.h"
  62. #include "utils.h"
  63. #include "queues.h"
  64. #include "statusdialog.h"
  65. #include "AddressOMini.h"
  66.  
  67. #include "myipm.h"
  68. #include "GetAttribute.h"
  69.  
  70.  
  71. /*---------- init/cleanup stuff ---------------------------------------------------------*/
  72.  
  73. OSErr InitIPM(void)
  74. {
  75.     OSErr err;
  76.     
  77.     gNumMessages = 0;
  78.     gNumDestinations = 0;
  79.     err = GetIdentity();
  80.     if (err!=noErr)
  81.         return err;
  82.     return MakeLocalQueue(&gIPMContext,&gIPMQueueRef);
  83. }
  84.  
  85.  
  86. void CloseIPM(void)
  87. {
  88.     OSErr err;
  89.     
  90.     err = RemoveLocalQueue(gIPMContext,&gLocalQueue);
  91.     if (err!=noErr)
  92.         DoError(err);
  93. }
  94.  
  95.  
  96. /*---------- queue management stuff ------------------------------------------------------*/
  97.  
  98.  
  99. OSErr MakeLocalQueue(IPMContextRef *context,IPMQueueRef *queueRef)
  100. {
  101.     IPMParamBlock pmBlock;
  102.     OSErr err;
  103.     
  104.     *context = 0;
  105.     *queueRef = 0;
  106.     
  107.     err = GetLocalQueueLocation(&gLocalQueue,kQueueName,gLocalQXtn);
  108.     if (err!=noErr)
  109.         return err;
  110.     
  111.     // create queue
  112.     
  113.     pmBlock.createQueuePB.queue = &gLocalQueue;
  114.     pmBlock.createQueuePB.identity = gIdentity;
  115.     pmBlock.createQueuePB.owner = nil;
  116.     pmBlock.createQueuePB.ioCompletion = nil;
  117.     IPMCreateQueue(&pmBlock,true);
  118.     err = WaitPBDone(&pmBlock);
  119.     if (err!=noErr && err!=kOCEAlreadyExists)
  120.         return err;
  121.     
  122.     // open context
  123.     
  124.     IPMOpenContext(&pmBlock,true);
  125.     err = WaitPBDone(&pmBlock);
  126.     if (err!=noErr)
  127.         return err;
  128.     *context = pmBlock.openContextPB.contextRef;
  129.     
  130.     // open queue
  131.     
  132.     pmBlock.openQueuePB.filter = nil;
  133.     pmBlock.openQueuePB.noteType = kIPMNewMsgMask;
  134.  
  135.     pmBlock.openQueuePB.notificationProc = OurIPMNotificationProc;
  136.     pmBlock.openQueuePB.userData = SetCurrentA5();
  137.     IPMOpenQueue(&pmBlock,true);
  138.     err = WaitPBDone(&pmBlock);
  139.     if (err!=noErr)
  140.         return err;
  141.     
  142.     gIPMQueueRef = pmBlock.openQueuePB.newQueueRef;
  143.     return noErr;
  144. }
  145.  
  146.  
  147. OSErr RemoveLocalQueue(IPMContextRef context,OCERecipient *localQueue)
  148. {
  149.     IPMParamBlock pmBlock;
  150.     OSErr err;
  151.     
  152.     if (context) {
  153.         pmBlock.closeContextPB.contextRef = context;
  154.         pmBlock.closeContextPB.ioCompletion = nil;
  155.         err = IPMCloseContext(&pmBlock,true);
  156.         err = WaitPBDone(&pmBlock);
  157.         if (err!=noErr)
  158.             return err;
  159.     }
  160.     
  161.     pmBlock.deleteQueuePB.queue = localQueue;
  162.     pmBlock.deleteQueuePB.identity = gIdentity;
  163.     pmBlock.deleteQueuePB.ioCompletion = nil;
  164.     IPMDeleteQueue(&pmBlock,true);
  165.     err = WaitPBDone(&pmBlock);
  166.     
  167.     return err;
  168. }
  169.  
  170.  
  171. OSErr GetLocalQueueLocation(OCERecipient *queue,StringPtr queueName,char *xtnValue)
  172. {
  173.     XPPParamBlock xppPB;
  174.     Str32 zoneName;
  175.     StringHandle machineName;
  176.     char *offset;
  177.     OSErr err;
  178.     short i;
  179.     
  180.     for (i=0; i<256; i++)
  181.         xtnValue[i] = '\0';
  182.         
  183.     xppPB.XCALL.xppTimeout = 3;
  184.     xppPB.XCALL.xppRetry = 4;
  185.     xppPB.XCALL.zipBuffPtr = (Ptr)&zoneName;
  186.     xppPB.XCALL.zipInfoField[0] = 0;
  187.     xppPB.XCALL.zipInfoField[1] = 0;
  188.     err = GetMyZone(&xppPB,false);
  189.     if (err!=noErr)
  190.         return err;
  191.     
  192.     machineName = GetString(kMachineNameResource);
  193.     if (ResError()!=noErr)
  194.         return ResError();
  195.     
  196.     offset = xtnValue;
  197.     BlockMove(*machineName,offset,(*machineName)[0]+1);
  198.     offset = offset+(*machineName)[0]+1;
  199.     
  200.     ReleaseResource((Handle)machineName);
  201.     
  202.     BlockMove(kIPMWSReceiverNBPType,offset,kIPMWSReceiverNBPType[0]+1);
  203.     offset = (offset+kIPMWSReceiverNBPType[0]+1);
  204.     
  205.     BlockMove(zoneName,offset,zoneName[0]+1);
  206.     offset = (offset+zoneName[0]+1);
  207.     
  208.     BlockMove(queueName,offset,queueName[0]+1);
  209.     offset = (offset+queueName[0]+1);
  210.     
  211.     queue->entitySpecifier = nil;    // we don't need one for direct specification
  212.     queue->extensionType = kOCEalanXtn;
  213.     queue->extensionValue = xtnValue;
  214.     queue->extensionSize = StripAddress(offset)-StripAddress(xtnValue);
  215.     
  216.     return noErr;
  217. }
  218.  
  219.  
  220. /*---------- message sending stuff ------------------------------------------------------*/
  221.  
  222.  
  223. OSErr SendIPMMessage(StringPtr message,OCEPackedRecipient *packedQueue)
  224. {
  225.     OSErr err,err2;
  226.     IPMParamBlock pmBlock;
  227.     OCERecipient queue;
  228.     RecordID entitySpecifier;
  229.     IPMProcHint procHint;
  230.     short i;
  231.     IPMMsgType msgType;
  232.     IPMSender sender;
  233.     RString messageTitle;
  234.     
  235.     // zero out proc hint
  236.     
  237.     for (i=0; i<sizeof(IPMProcHint); i++)
  238.         procHint[i] = 0;
  239.     
  240.     // unpack destination recipient
  241.     
  242.     OCEUnpackDSSpec((PackedDSSpec*)packedQueue,&queue,&entitySpecifier);
  243.  
  244.     // get message type and sender
  245.     
  246.     GetOurMessageType(&msgType);
  247.     GetOurSender(&sender);
  248.     
  249.     // make a new message
  250.     
  251.     pmBlock.newMsgPB.ioCompletion = nil;
  252.     pmBlock.newMsgPB.recipient = &queue;
  253.     
  254.     pmBlock.newMsgPB.replyQueue = &gLocalQueue;        
  255.     pmBlock.newMsgPB.procHint = procHint;
  256.     
  257.     pmBlock.newMsgPB.msgType = &msgType;
  258.     pmBlock.newMsgPB.identity = gIdentity;
  259.     pmBlock.newMsgPB.sender = &sender;
  260.     IPMNewMsg(&pmBlock,true);
  261.     err = WaitPBDone(&pmBlock);
  262.     if (err!=noErr)
  263.         return err;
  264.     
  265.     // make a block within that message
  266.     
  267.     pmBlock.newBlockPB.msgRef = pmBlock.newMsgPB.newMsgRef;
  268.     pmBlock.newBlockPB.blockType.msgType = kAppBlockType;
  269.     pmBlock.newBlockPB.blockType.msgCreator = kAppCreator;
  270.     pmBlock.newBlockPB.refCon = 0;
  271.     IPMNewBlock(&pmBlock,true);
  272.     err = WaitPBDone(&pmBlock);
  273.     if (err==noErr) {
  274.  
  275.         // write block data
  276.         pmBlock.writeMsgPB.offset = pmBlock.newBlockPB.startingOffset;
  277.         pmBlock.writeMsgPB.mode = kIPMFromStart;
  278.         pmBlock.writeMsgPB.count = message[0]+1;
  279.         pmBlock.writeMsgPB.buffer = (Ptr)message;
  280.         pmBlock.writeMsgPB.currentBlock = false;    /* offset from beginning of main body */
  281.         IPMWriteMsg(&pmBlock,true);
  282.         err = WaitPBDone(&pmBlock);
  283.  
  284.     }
  285.     
  286.     // end the message
  287.     
  288.     OCECToRString((char *)"message\n",smRoman,&messageTitle,kRStringMaxBytes);
  289.  
  290.     pmBlock.endMsgPB.deliveryNotification = 0;
  291.     pmBlock.endMsgPB.priority = kIPMNormalPriority;
  292.     pmBlock.endMsgPB.cancel = (err!=noErr);
  293.     pmBlock.endMsgPB.signature = nil;
  294.     pmBlock.endMsgPB.signatureSize = 0;
  295.     pmBlock.endMsgPB.signatureContext = nil;
  296.     pmBlock.endMsgPB.msgTitle = &messageTitle;
  297.     IPMEndMsg(&pmBlock,true);
  298.     err2 = WaitPBDone(&pmBlock);
  299.     
  300.     if (err!=noErr)
  301.         return err;
  302.     else
  303.         return err2;
  304. }
  305.  
  306.  
  307.  
  308. OSErr GetIdentityAndSaveIt (void)
  309. {
  310.     OSErr            err;
  311.     SDPIdentityKind     selectedKind;
  312.  
  313.     if ((err = SDPPromptForID (&gIdentity, "\pPlease Validate Your Identity:",
  314.                                 "\pPlease Validate Your Identity:",
  315.                                 "\pPlease Validate Your Identity:", 
  316.                                 OCEGetIndRecordType (kUserRecTypeNum),
  317.                                 kSDPSpecificIdentityMask, &selectedKind, NULL, 0/*NULL*/)) != noErr)
  318.         gIdentity = 0L;
  319.  
  320.     return (err);
  321. }
  322.  
  323.  
  324. OSErr GetNewIdentityAndSaveIt (AuthIdentity *theIdentity)
  325. {
  326.     OSErr            err;
  327.     SDPIdentityKind     selectedKind;
  328.  
  329.     if ((err = SDPPromptForID (theIdentity, "\pEnter Authentication Identity Of The Queue Creator:",
  330.                                 "\pEnter Authentication Identity Of The Queue Creator:",
  331.                                 "\pEnter Authentication Identity Of The Queue Creator:", 
  332.                                 OCEGetIndRecordType (kUserRecTypeNum),
  333.                                 kSDPSpecificIdentityMask, &selectedKind, NULL, 0/*NULL*/)) != noErr)
  334.         *theIdentity = 0L;
  335.  
  336.     return (err);
  337. }
  338.  
  339.  
  340. OSErr MyCreateQueue(StringPtr TheQName,OCEPackedRecipient **pmPackedRecipient)
  341. {
  342. OSErr err;
  343. IPMParamBlock IPMpb;
  344. OCERecipient theRecp,OwnerRecp;
  345. RecordID QLocRid,OwnerRid,testRecID;
  346. Boolean gotAddress;
  347. PackedDSSpecPtr packedReply,packedReply2;
  348. PackedRecordIDPtr testPckRecID;
  349. unsigned short ridSize;
  350. //AuthIdentity theIdentity;
  351. IPMEntityNameExtension TheExtn;
  352. unsigned long recipLength;
  353.  
  354.  
  355.     gotAddress = AddressOMini(&packedReply,gTypesList,0,gIdentity,
  356.             kEnumAllMask,"\pSelect The Server Record:",kMatchAll);
  357.  
  358.     if (gotAddress==false)
  359.         return kUserCancelled;
  360.  
  361.     if (packedReply) 
  362.     {
  363.         OCEUnpackDSSpec(packedReply,&theRecp,&QLocRid);
  364.  
  365.         TheExtn.subExtensionType = kOCEQnamXtn;    //    'qnam'
  366.         pstrcpy((Ptr)&TheExtn.u.queue.queueName,TheQName);
  367.  
  368.         theRecp.extensionType = kOCEentnXtn;    // 'entn'
  369.         theRecp.extensionValue = (Ptr)&TheExtn;
  370.         theRecp.extensionSize = (TheExtn.u.queue.queueName[0] + 1) + sizeof(OSType);        
  371.         
  372.         IPMpb.createQueuePB.queue = &theRecp;
  373.  
  374. #if 0        
  375.             // let user identify the creator of the queue
  376.         GetNewIdentityAndSaveIt (&theIdentity);
  377.         IPMpb.createQueuePB.identity = theIdentity;
  378. #endif
  379. IPMpb.createQueuePB.identity = gIdentity;
  380.  
  381.         gotAddress = AddressOMini(&packedReply2,gTypesList,0,gIdentity,
  382.                 kEnumAllMask,"\pSelect The User Record Of The Queue Owner:",kMatchAll);
  383.     
  384.         if (gotAddress==false)
  385.             return kUserCancelled;
  386.     
  387.         if (packedReply2) 
  388.         {
  389.             OCEUnpackDSSpec(packedReply2,&OwnerRecp,&OwnerRid);
  390.  
  391.             OCENewRecordID(OwnerRid.rli,&OwnerRid.local,&testRecID);
  392.             ridSize = OCEPackedRecordIDSize(&OwnerRid);
  393.             testPckRecID = (PackedRecordIDPtr)NewPtr(ridSize);
  394.             if ((err = MemError()) != noErr)
  395.                 return err;
  396.             if ((err = OCEPackRecordID(&testRecID,testPckRecID,ridSize)) != noErr)
  397.                 return err;
  398.             
  399.             IPMpb.createQueuePB.owner = testPckRecID;
  400.             if ((err = IPMCreateQueue(&IPMpb,false)) != noErr)
  401.                 return err;
  402.         }
  403.         if (testPckRecID != nil)
  404.             DisposePtr((Ptr)testPckRecID);
  405.             
  406.         recipLength = OCEPackedDSSpecSize(&theRecp);
  407.         *pmPackedRecipient = NewPtrChk(recipLength);
  408.         if ((err=MemError())==noErr) 
  409.             OCEPackDSSpec(&theRecp,(PackedDSSpec *)*pmPackedRecipient,recipLength);
  410.         else
  411.             return err;
  412.     }
  413.     
  414.     return err;
  415. }
  416.  
  417. OSErr MyOpenQueue(OCERecipient *RecP)
  418. {
  419. OSErr err;
  420. IPMParamBlock IPMpb;
  421. IPMContextRef cRef;
  422.  
  423.  
  424.     IPMpb.openContextPB.ioCompletion = nil;
  425.     if ((err = IPMOpenContext(&IPMpb,false)) != noErr)
  426.         return err;
  427.     else
  428.         cRef = IPMpb.openContextPB.contextRef;
  429.     
  430.     IPMpb.openQueuePB.ioCompletion = nil;
  431.     IPMpb.openQueuePB.contextRef = cRef;
  432.     
  433.     IPMpb.openQueuePB.queue = RecP;
  434.     IPMpb.openQueuePB.identity = gIdentity;
  435.     IPMpb.openQueuePB.filter = nil;
  436.     
  437.     if ((err = IPMOpenQueue(&IPMpb,false)) != noErr)
  438.         return err;
  439.  
  440.     return err;
  441. }
  442.  
  443. OSErr OpenQueueOnRemoteMachine(StringPtr Qname,OCEPackedRecipient **pmPackedRecipient)
  444. {
  445. OSErr err;
  446. PackedDSSpecPtr packedReply;
  447. PackedRStringListHandle catTypes = nil;
  448. OCERecipient ipmRecipient;
  449. unsigned long recipLength;
  450. Boolean gotAddress;
  451. RecordID rid;
  452. IPMEntityNameExtension myExtn;
  453.  
  454.  
  455.  
  456. //    if ((err = GetIdentityAndSaveIt()) == noErr)
  457. //    {
  458.         gotAddress = AddressOMini(&packedReply,gTypesList,0,gIdentity,
  459.                 kEnumAllMask,"\pSelect The Server Record:",kMatchAll);
  460.     
  461.         if (gotAddress==false)
  462.             return kUserCancelled;
  463.     
  464.         if (packedReply) 
  465.         {
  466.             OCEUnpackDSSpec(packedReply,&ipmRecipient,&rid);
  467.             ipmRecipient.extensionType = kOCEentnXtn;    // 'entn'
  468.             
  469.             myExtn.subExtensionType = kOCEQnamXtn;    //    'qnam'
  470.             pstrcpy((Ptr)&myExtn.u.queue.queueName,Qname);
  471.             
  472.             ipmRecipient.extensionSize = (myExtn.u.queue.queueName[0] + 1) + sizeof(OSType);
  473.             ipmRecipient.extensionValue = (Ptr)&myExtn;
  474.     
  475.             if ((err = MyOpenQueue(&ipmRecipient)) == noErr)
  476.             {
  477.         
  478.                 recipLength = OCEPackedDSSpecSize(&ipmRecipient);
  479.                 *pmPackedRecipient = NewPtrChk(recipLength);
  480.                 if ((err=MemError())==noErr) 
  481.                     OCEPackDSSpec(&ipmRecipient,(PackedDSSpec *)*pmPackedRecipient,recipLength);
  482.                 else
  483.                     return err;
  484.             }
  485.     
  486.         }
  487. //    }
  488.     
  489.     return err;
  490. }
  491.  
  492.  
  493.  
  494. OSErr GetSingleAttrForRecipient(OCEPackedRecipient **pmPackedRecipient,
  495.                                 const OCEAttributeTypeIndex stringIndex)
  496. {
  497. OSErr err;
  498. PackedDSSpecPtr packedReply;
  499. unsigned long recipLength;
  500. Boolean gotAddress;
  501. AttributePtr theAttribute;
  502. OCERecipient dss;
  503. RecordID rid;
  504. IPMEntityNameExtension myExtn;
  505.  
  506.  
  507.  
  508.     gotAddress = AddressOMini(&packedReply,gTypesList/*&gTypesList*/,0,gIdentity,
  509.             kEnumAllMask,"\pSelect The User Record:",kMatchAll);
  510.  
  511.     if (gotAddress==false)
  512.         return kUserCancelled;
  513.  
  514.     if (packedReply) 
  515.     {
  516.         OCEUnpackDSSpec(packedReply,&dss,&rid);
  517.  
  518.         if ((err = GetAttributeFromRID (&rid, OCEGetIndAttributeType (stringIndex),
  519.                                     &theAttribute, gIdentity)) != noErr)
  520.             return err;
  521.         dss.extensionType = kOCEentnXtn;    // 'entn'
  522.  
  523.         myExtn.subExtensionType = kOCEAttrXtn;    //    'attr'
  524.         OCECopyRString((RStringPtr)&theAttribute->attributeType,(RStringPtr)OCEGetIndAttributeType(stringIndex),kAttributeTypeMaxBytes);
  525.  
  526. // #################
  527.         dss.extensionSize = sizeof(ProtoRString) + theAttribute->attributeType.dataLength + sizeof(OSType);
  528.         dss.extensionValue = (Ptr)&myExtn;
  529.  
  530.         recipLength = OCEPackedDSSpecSize(&dss);
  531.         *pmPackedRecipient = NewPtrChk(recipLength);
  532.         if ((err=MemError())==noErr)
  533.         OCEPackDSSpec(&dss,(PackedDSSpec *)*pmPackedRecipient,recipLength);
  534.  
  535.         DisposPtr((Ptr)packedReply);
  536.  
  537.     }
  538.     
  539.     return err;
  540. }
  541.  
  542.  
  543.  
  544.  
  545.  
  546.  
  547. OSErr GetIPMDestination(OCEPackedRecipient **pmPackedRecipient)
  548. {
  549.     PackedDSSpecPtr packedReply;
  550.     OSErr err;
  551.     RString addressCategory;
  552.     unsigned short numTypes;
  553.     PackedRStringListHandle catTypes;
  554.     RString *typeList[kMaxPathParts];
  555.     unsigned char hState;
  556.     OCERecipient *ipmRecipient;
  557.     char newXtnValue[256];
  558.     unsigned long newXtnLength,recipLength;
  559.     SMPRecipientDescriptorPtr recipList,freeRecip;
  560.     Boolean gotAddress;
  561.     
  562.     /* display address records */
  563.     
  564.     OCECToRString(kDETCategoryAddressItems,smRoman,&addressCategory,kRStringMaxBytes);
  565.     err = SDPGetCategoryTypes(&addressCategory,&catTypes);
  566.     if (err!=noErr)
  567.         return err;
  568.     hState = HGetState((Handle)catTypes);
  569.     HLock((Handle)catTypes);
  570.     numTypes = OCEUnpackPathName(*catTypes,typeList,kMaxPathParts);    
  571.  
  572.     gotAddress = AddressOMini(&packedReply,typeList,numTypes,gIdentity,
  573.             kEnumDistinguishedNameMask|kEnumAliasMask|kEnumDNodeMask,"\pSelect Atalk Address:",kExactMatch);
  574.  
  575.     HSetState((Handle)catTypes,hState);
  576.     if (gotAddress==false)
  577.         return kUserCancelled;
  578.     
  579.     if (packedReply) {
  580.         err = SMPResolveToRecipient(packedReply,&recipList,gIdentity);
  581.         ipmRecipient = &recipList->theAddress;
  582.         newXtnLength = ipmRecipient->extensionSize;
  583.         BlockMove(ipmRecipient->extensionValue,newXtnValue,newXtnLength);
  584.         BlockMove(kQueueName,newXtnValue+newXtnLength,kQueueName[0]+1);
  585.         newXtnLength += kQueueName[0]+1;
  586.         ipmRecipient->extensionSize = newXtnLength;
  587.         ipmRecipient->extensionValue = newXtnValue;
  588.     }
  589.  
  590.     // pack the recipient
  591.     
  592.     recipLength = OCEPackedDSSpecSize(ipmRecipient);
  593.     *pmPackedRecipient = NewPtrChk(recipLength);
  594.     if ((err=MemError())==noErr) {
  595.         OCEPackDSSpec(ipmRecipient,(PackedDSSpec *)*pmPackedRecipient,recipLength);
  596.     }
  597.     DisposPtr((Ptr)packedReply);
  598.  
  599.     // free the resolvetorecipients result
  600.     
  601.     while (recipList!=nil) {
  602.         freeRecip = recipList;
  603.         recipList = recipList->next;
  604.         DisposPtrChk(freeRecip->recipient);
  605.         DisposPtrChk(freeRecip);
  606.     }
  607.     
  608.     return err;
  609. }
  610.  
  611.  
  612. void GetDestAsString(short destNum,StringPtr destStr)
  613. {
  614.     OCERecipient recipient;
  615.     RecordID entitySpecifier;
  616.     StringPtr displayName;
  617.     
  618.     OCEUnpackDSSpec((PackedDSSpec *)gDestList[destNum],&recipient,&entitySpecifier);
  619.     displayName = OCERToPString(entitySpecifier.local.recordName);
  620.     pstrcpy(destStr,displayName);
  621. }
  622.  
  623.  
  624. void r2cString(RString *rStr,char *cStr)
  625. {
  626.     StringPtr pStr;
  627.     
  628.     pStr = OCERToPString(rStr);
  629.     pstrcpy((StringPtr)cStr,pStr);
  630.     p2cstr((StringPtr)cStr);
  631. }
  632.  
  633.  
  634. void GetOurMessageType(IPMMsgType *msgType)
  635. {
  636.     msgType->format = kIPMOSFormatType;
  637.     msgType->theType.msgOSType.msgCreator = kAppCreator;
  638.     msgType->theType.msgOSType.msgType = kAppMessageType;
  639. }
  640.  
  641.  
  642. void GetOurSender(IPMSender *sender)
  643. {
  644.     Str255 appName;
  645.     Handle appParms;
  646.     short refNum;
  647.     
  648.     GetAppParms(appName,&refNum,&appParms);
  649.     OCEPToRString(appName,smSystemScript,&sender->theSender.rString,kRStringMaxBytes);
  650.     sender->sendTag = kIPMSenderRStringTag;
  651. }
  652.  
  653.  
  654. OSErr GetIdentity(void)
  655. {
  656.     OSErr err;
  657.     SDPIdentityKind idKind;
  658.     AuthGetLocalIdentityPB pBlock;
  659.     
  660.     err = AuthGetLocalIdentity((AuthParamBlockPtr)&pBlock,false);
  661.  
  662.     if (err!=noErr)
  663.         err = SDPPromptForID(&gIdentity,nil,nil,kLocalIDPrompt,nil,kSDPLocalIdentityMask,&idKind,nil,0);
  664.     else
  665.         gIdentity = pBlock.theLocalIdentity;
  666.         
  667.     return err;
  668. }
  669.  
  670.  
  671.  
  672. /*---------- message receiving stuff ------------------------------------------------------*/
  673.  
  674.  
  675. pascal void OurIPMNotificationProc(IPMQueueRef pmQ, IPMSeqNum pmSeq, IPMNotificationType noteType, unsigned long userData)
  676. {
  677.     long savedA5;
  678.     unsigned char noteTypeChar;
  679.  
  680.     noteTypeChar = (unsigned char) (noteType &= 0x000000ff);
  681.     savedA5 = SetA5(userData);
  682.     EnqueueNotification(pmQ,pmSeq,noteType);
  683.     SetA5(savedA5);
  684. }
  685.  
  686.  
  687. void EnqueueNotification(IPMQueueRef pmQ, IPMSeqNum pmSeq, IPMNotificationType noteType)
  688. {
  689.     MyQElemPtr qBlock;
  690.     
  691.     qBlock = GetUnusedQBlock();
  692.     if (!qBlock) {
  693.         DoError(kNoMemory);
  694.         return;
  695.     }
  696.     
  697.     qBlock->pmQ = pmQ;
  698.     qBlock->pmSeq = pmSeq;
  699.     qBlock->noteType = noteType;
  700.     
  701.     StoreCompletedQBlock(qBlock);
  702. }
  703.  
  704.  
  705. void ProcessNotification(MyQElemPtr qBlock)
  706. {
  707.     OSErr err;
  708.     
  709.     err = noErr;
  710.     
  711.     if (qBlock->noteType==kIPMNewMsgMask)
  712.         err = ProcessNewMessage(qBlock->pmQ,qBlock->pmSeq);
  713.     
  714.     if (err!=noErr)
  715.         DoError(err);
  716.         
  717.     RecycleFreeQBlock(qBlock);
  718. }
  719.  
  720.  
  721. OSErr ProcessNewMessage(IPMQueueRef pmQ, IPMSeqNum pmSeq)
  722. {
  723.     OSErr err;
  724.     IPMParamBlock pmBlock;
  725.     IPMMsgInfo msgInfo;
  726.     Str255 msgBuffer;
  727.  
  728.     // open the message
  729.     
  730.     pmBlock.openMsgPB.ioCompletion = nil;
  731.     pmBlock.openMsgPB.queueRef = pmQ;
  732.     pmBlock.openMsgPB.sequenceNum = pmSeq;
  733.     pmBlock.openMsgPB.exactMatch = true;
  734.     IPMOpenMsg(&pmBlock,true);
  735.     err = WaitPBDone(&pmBlock);
  736.     if (err!=noErr)
  737.         return err;
  738.     
  739.     // get message header
  740.     pmBlock.getMsgInfoPB.msgRef = pmBlock.openMsgPB.newMsgRef;
  741.     pmBlock.getMsgInfoPB.info = &msgInfo;
  742.     IPMGetMsgInfo(&pmBlock,true);
  743.     err = WaitPBDone(&pmBlock);
  744.     if (err!=noErr)
  745.         return BailMessageProcessing(&pmBlock,err);
  746.     
  747.     // get message block index
  748.     
  749.     pmBlock.getBlkIndexPB.blockType.msgType = kAppBlockType;
  750.     pmBlock.getBlkIndexPB.blockType.msgCreator = kAppCreator;
  751.     pmBlock.getBlkIndexPB.index = 1;
  752.     pmBlock.getBlkIndexPB.startingFrom = 1;
  753.     IPMGetBlkIndex(&pmBlock,true);
  754.     err = WaitPBDone(&pmBlock);
  755.     if (err!=noErr)
  756.         return BailMessageProcessing(&pmBlock,err);
  757.     
  758.     // get the message block
  759.     pmBlock.readMsgPB.blockIndex = pmBlock.getBlkIndexPB.actualBlockIndex;
  760.     pmBlock.readMsgPB.mode = kIPMFromStart;
  761.     pmBlock.readMsgPB.offset = 0;
  762.     pmBlock.readMsgPB.count = sizeof(Str255);
  763.     pmBlock.readMsgPB.buffer = (Ptr)&msgBuffer;
  764.     IPMReadMsg(&pmBlock,true);
  765.     err = WaitPBDone(&pmBlock);
  766.     if (err!=noErr)
  767.         return BailMessageProcessing(&pmBlock,err);
  768.  
  769.     // add message to list
  770.     
  771.     if (gNumMessages!=kMaxMessages) {
  772.         pstrcpy(gMessageList[gNumMessages],msgBuffer);
  773.         AddItemToList(gNumMessages,kMsgListDItem);
  774.         gNumMessages++;
  775.     }
  776.     else SysBeep(1);    // no room in list
  777.  
  778.     return BailMessageProcessing(&pmBlock,err);
  779. }
  780.  
  781.  
  782. /* delete the message and exit with the passed in error code */
  783.  
  784. OSErr BailMessageProcessing(IPMParamBlock *pmBlock,OSErr err)
  785. {
  786.     OSErr err2;
  787.     
  788.     // delete the message
  789.  
  790.     pmBlock->closeMsgPB.deleteMsg = true;
  791.     IPMCloseMsg(pmBlock,true);
  792.     err2 = WaitPBDone(pmBlock);
  793.     
  794.     if (err==noErr)
  795.         return err2;
  796.     else
  797.         return err;
  798. }
  799.  
  800.